package com.allwees.bs.c.module.user.service.impl;

import com.google.common.collect.Lists;
import com.allwees.bs.c.module.merchant.entity.StoreEntity;
import com.allwees.bs.c.module.merchant.repository.StoreRepository;
import com.allwees.bs.c.module.product.dto.ProductDetailsDTO;
import com.allwees.bs.c.module.product.entity.ProductEntity;
import com.allwees.bs.c.module.product.mapper.ProductMapper;
import com.allwees.bs.c.module.product.repository.ProductRepository;
import com.allwees.bs.c.module.product.service.ProductService;
import com.allwees.bs.c.module.user.dto.ProductCollectionDto;
import com.allwees.bs.c.module.user.dto.StoreCollectionDto;
import com.allwees.bs.c.module.user.entity.ProductCollectionEntity;
import com.allwees.bs.c.module.user.entity.StoreCollectionEntity;
import com.allwees.bs.c.module.user.mapper.CollectionMapper;
import com.allwees.bs.c.module.user.repository.ProductCollectionRepository;
import com.allwees.bs.c.module.user.repository.StoreCollectionRepository;
import com.allwees.bs.c.module.user.service.ICollectionService;
import com.allwees.bs.core.modelbase.page.PageParams;
import com.allwees.bs.core.modelbase.page.PaginateDTO;
import com.allwees.core.common.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

@Service
public class CollectionServiceImpl implements ICollectionService {
	@Autowired
	private ProductCollectionRepository productCollRepository;

	@Autowired
	private StoreCollectionRepository storeCollRepository;

	@Autowired
	private ProductRepository productRepository;

	@Autowired
	private ProductService productService;

	@Autowired
	private StoreRepository storeRepository;

	@Autowired
	private CollectionMapper collMapper;

	@Autowired
	private ProductMapper productMapper;

	@Override
	@Transactional(rollbackOn = Exception.class)
	public void collProduct(String userUuid, String productUuid) {
		ProductDetailsDTO product = productService.findProductByUuid(productUuid).filter(false);

		if(Objects.isNull(product)) {
			//throw BusinessException.getInstance(ResultEnum.NOT_FOUND);
			return;
		}

		Set<String> productUuids = new HashSet<>();
		productUuids.add(productUuid);

		Set<String> collProductUuids = productCollRepository.findCollProductUuids(userUuid, productUuids);
		if (!CollectionUtils.isEmpty(collProductUuids)) {
			//throw BusinessException.getInstance(ResultEnum.ALREADY_EXISTS);
			return;
		}
		ProductCollectionEntity entity = ProductCollectionEntity.builder().userUuid(userUuid).productUuid(productUuid).build();
		productCollRepository.save(entity);
		productRepository.increaseTotalCollectionsById(productUuid);
	}

	@Override
	@Transactional(rollbackOn = Exception.class)
	public void cancelCollProduct(String userUuid, String productUuid) {
		List<String> uuids = new ArrayList<>();
		uuids.add(productUuid);
		Set<String> collIds = productCollRepository.findCollProductUuids(userUuid, new HashSet<>(uuids));
		if(collIds.isEmpty()) {
			return;
		}
		productCollRepository.cancelForUser(userUuid, uuids);
		productRepository.decreaseTotalCollectionsByIds(uuids);
	}

	@Override
	public PaginateDTO<ProductCollectionDto> getCollProduct(String userUuid, PageParams pageParams) {
		Page<ProductCollectionEntity> page = productCollRepository.findCollProduct(userUuid, pageParams.toPageable());

		if (CollectionUtils.isEmpty(page.getContent())) {
			return PaginateDTO.of(0, 0, pageParams);
		}

		List<ProductCollectionDto> list = Lists.newArrayList();

		page.getContent().forEach(o -> {
			ProductDetailsDTO product = productService.findProductByUuid(o.getProductUuid());

			ProductCollectionDto productCollectionDto = new ProductCollectionDto(product, o);
			//收藏列表中的商品必定是收藏了的
			productCollectionDto.getProductDto().setUserIsCollection(true);
			list.add(productCollectionDto);
		});

		PaginateDTO<ProductCollectionDto> pageResult = PaginateDTO.of(page.getTotalElements(), list.size(), pageParams);
		pageResult.setResults(list);

		return pageResult;
	}

	@Override
	@Transactional(rollbackOn = Exception.class)
	public void collStore(String userUuid, String storeUuid) {
		StoreEntity store = storeRepository.getByUuid(storeUuid);

		if(Objects.isNull(store)) {
			//throw BusinessException.getInstance(ResultEnum.NOT_FOUND);
			return;
		}

		long count = storeCollRepository.countByUserAndStoreId(userUuid, storeUuid);
		if(count > 0) {
			//throw BusinessException.getInstance(ResultEnum.ALREADY_EXISTS);
			return;
		}
		StoreCollectionEntity entity = new StoreCollectionEntity(userUuid, store);
		storeCollRepository.save(entity);
		store.setTotalCollections(store.getTotalCollections() + 1);
	}

	@Override
	@Transactional(rollbackOn = Exception.class)
	public void cancelCollStore(String userUuid, String storeUuid) {
		List<String> uuids = new ArrayList<>();
		uuids.add(storeUuid);
		List<String> collIds = storeCollRepository.getOnes(userUuid, uuids);
		if(collIds.isEmpty()) {
			return;
		}
		storeCollRepository.cancelForUser(userUuid, uuids);
		storeRepository.incTotalCollectionsByIds(uuids);
	}

	@Override
	public PaginateDTO<StoreCollectionDto> getCollStore(String userUuid, PageParams pageParams) {
		Page<StoreCollectionEntity> page = storeCollRepository.findCollStore(userUuid, pageParams.toPageable());
		PaginateDTO<StoreCollectionDto> paginateStore = collMapper.entity2StoreCollDto(page, pageParams);

		final Long afterTime = DateUtil.nowTime() - 7L * 24L * 60L * 60L * 10000L;
		paginateStore.getResults().forEach(store -> {
			List<ProductEntity> productEntities = this.storeRepository.findStoreRecommendProducts(store.getStoreDto().getUuid(), afterTime,
					PageRequest.of(0, 3));
			store.getStoreDto().setRecommendProducts(this.productMapper.entity2DTOWithoutStore(productEntities));
		});

		return paginateStore;
	}

}
